#include <gtest/gtest.h>

struct BaseException : std::exception {
    std::string msg{};

    [[nodiscard]] char const *what() const noexcept override { return msg.c_str(); }
};

struct UnexpectedException : BaseException {
    explicit UnexpectedException(const std::string &msg = "") {
        this->msg += "UnexpectedException(" + msg + ")";
    };
};

int Foo(int a, int b) {
    if (a == 0 || b == 0) {
        throw UnexpectedException("don't do that");
    }
    int c = a % b;
    if (c == 0)
        return b;
    return Foo(b, c);
}

TEST(FooTest, HandleNoneZeroInput
) {
    EXPECT_EQ(2, Foo(4, 10)) << "function result error";
    EXPECT_THROW(Foo(0, 18), UnexpectedException);
}